package jp.sourceforge.akjrcp.audio.wavmix;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.sound.sampled.UnsupportedAudioFileException;

import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.audio.AudioProgressListener;
import jp.sourceforge.akjrcp.audio.wav.WaveUtils;
import jp.sourceforge.akjrcp.commons.ui.EditableFileList;
import jp.sourceforge.akjrcp.commons.ui.FileDirChoicer;
import jp.sourceforge.akjrcp.commons.ui.AbstractFileDirChoicer.FileStatusChangeEvent;
import jp.sourceforge.akjrcp.commons.ui.AbstractFileDirChoicer.FileStatusChangeListener;
import jp.sourceforge.akjrcp.commons.ui.widget.WidgetBuilder;
import jp.sourceforge.akjrcp.commons.util.FileNameUtils;
import jp.sourceforge.akjrcp.util.ExecutingControler;
import jp.sourceforge.akjrcp.util.SelectionUtils;
import jp.sourceforge.akjrcp.util.ExecutingControler.ExecutingControlButton;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.part.ViewPart;

public class WavJoinerViewer extends ViewPart {
	public static Log log=LogFactory.getLog(WavJoinerViewer.class);
	
	public static final String ID = WavJoinerViewer.class.getName();
	
	private WavJoinExecute wavToJoinExecuter;
	private FileDirChoicer outputFileChooser;
	private Label statusLabel;
	private EditableFileList fileList;

	private Button makeAudacityLabel;
	@Override
	public void createPartControl(Composite parent) {
      wavToJoinExecuter = new WavJoinExecute();
      FileSelected selectedListener=new FileSelected();	

		parent.setLayout(new GridLayout(1,false));
		
		fileList = new EditableFileList(parent,SWT.NULL);
		fileList.setLayoutData(new GridData(GridData.FILL_BOTH));
		fileList.setFilterExtension("*.wav");
		
		fileList.setInput(new ArrayList());
		fileList.addPropertyChangeListener(new IPropertyChangeListener(){

			public void propertyChange(PropertyChangeEvent event) {
				updateStatus();
			}});
		fileList.addSelectionChangedListener(new ISelectionChangedListener(){

			public void selectionChanged(SelectionChangedEvent event) {
				ISelection selection=event.getSelection();
				
				File selectFile=SelectionUtils.getSelectFile(selection);
				if(selectFile!=null){
					//imageCanvas.setImagePath(selectFile.getAbsolutePath());
				}else{
				//	imageCanvas.setImagePath(null);
				}
			}});
		
		Composite options=WidgetBuilder.createGridLayoutComposite(parent, SWT.NULL,4,false);
		makeAudacityLabel = WidgetBuilder.createCheckButton(options, Messages.getString("wavjoin.audacity_label"), true);
		outputFileChooser = new FileDirChoicer(parent,SWT.BORDER,FileDirChoicer.SAVE,Messages.getString("wavjoin.wav"),true);
		outputFileChooser.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		outputFileChooser.setFilterExtensions(new String[]{"*.wav"});
		outputFileChooser.addFileListChangeListener(selectedListener);
		
		Composite exec_label=WidgetBuilder.createGridLayoutComposite(parent,SWT.NULL,2, false);
		exec_label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		ExecutingControlButton exec=new ExecutingControlButton(exec_label,SWT.NULL,wavToJoinExecuter,
				Messages.getString("wavjoin.execute"),Messages.getString("cancel"));
		
		statusLabel = new Label(exec_label,SWT.NULL);
		statusLabel.setForeground(new Color(null,new RGB(255,0,0)));
		
		updateStatus();
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub
		
	}
	
	public class FileSelected implements FileStatusChangeListener{

		public void addList(FileStatusChangeEvent event) {
			
			updateStatus();
		}

		public void removeList(FileStatusChangeEvent event) {
			updateStatus();
		}
		
	}
	
	public void updateStatus() {
		//update label.
		if(wavToJoinExecuter.canExecute()){
			if(new File(outputFileChooser.getAbsoluteFilePath()).exists()){
				statusLabel.setText(Messages.getString("wavjoin.warn_overwrite"));
			}else{
			statusLabel.setText("");
			}
		}else{
			if(fileList.countFiles()==0){
				statusLabel.setText(Messages.getString("wavjoin.choose_input"));
			}else if(outputFileChooser.getAbsoluteFilePath().equals("")){
				statusLabel.setText(Messages.getString("wavjoin.choose_output"));
			}
		}
		
		// enable buttons and status.
		wavToJoinExecuter.updateControlSwitch();
	}

	public class WavJoinExecute extends ExecutingControler{

		private boolean makeAudacityLabel_value;
		String outputFile_value;
		File[] selectedFiles;
		AudioProgressListener listener;
		@Override
		public void afterExecute() {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void beforeExecute() {
			selectedFiles=fileList.getFileList();
			outputFile_value=outputFileChooser.getAbsoluteFilePath();
			makeAudacityLabel_value=makeAudacityLabel.getSelection();
		}

		@Override
		public boolean canExecute() {
			return  fileList.countFiles()>0 && !outputFileChooser.getAbsoluteFilePath().equals("");
		}

		@Override
		public void cancelExecuting() {
			if(listener!=null){
				listener.setStopped(true);
			}
		}

		@Override
		public void inExecute() {
			listener=new AudioProgressListener(){
				private boolean stopped;
				@Override
				public void worked(int step) {

				}
				@Override
				public boolean isStopped() {
					// TODO Auto-generated method stub
					return stopped;
				}
				@Override
				public void setStopped(boolean bool) {
					stopped=bool;
				}};
				
				//validate check;
				String text="";
				long current=0;
				for (int i = 0; i < selectedFiles.length; i++) {
					log.trace(selectedFiles[i].getAbsolutePath());
					long ms=WaveUtils.countAudioMillisecond(selectedFiles[i]);
					text+=""+current/1000.0+"\t"+(current+ms)/1000.0+"\t";
					text+=FileNameUtils.getRemovedExtensionName(selectedFiles[i].getName());
					text+="\r\n";
					current+=ms;
				}
				
				//join
				try {
					File output=new File(outputFile_value);
					WaveUtils.mixSameFormatWaveFile(output, selectedFiles, listener);
					FileUtils.writeStringToFile(new File(FileNameUtils.getChangedExtensionName(output, "audacity.txt")), text,"UTF-8");
				} catch (UnsupportedAudioFileException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		
	}
}
